package com.design.strategy.template.framework;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * 封装所有处理流程的抽象类
 *
 * @Author: cong zhi
 * @CreateDate: 2021/4/3 9:00
 * @UpdateUser: cong zhi
 * @UpdateDate: 2021/4/3 9:00
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
public abstract class JdbcTemplate {


    private DataSource dataSource;

    public JdbcTemplate(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public final List<?> executeQuery(String sql, RowMapper<?> rowMapper, Object[] values) {
        try {
            // 1、获取连接
            Connection conn = this.getConnection();
            // 2、创建语句集
            PreparedStatement pstmt = this.createPreparedStatement(conn, sql);
            // 3、执行语句集
            ResultSet rs = this.executeQuery(pstmt, values);
            // 4、处理语句集
            List<?> result = this.parseResultSet(rs, rowMapper);
            // 5、关闭结果集
            rs.close();
            // 6、关闭语句集
            pstmt.close();
            // 7、关闭连接
            conn.close();
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private List<?> parseResultSet(ResultSet rs, RowMapper<?> rowMapper) throws Exception {
        List<Object> result = new ArrayList<>();
        int rowNum = 0;
        while (rs.next()) {
            result.add(rowMapper.mapRow(rs, rowNum));
        }
        return result;
    }

    private ResultSet executeQuery(PreparedStatement pstmt, Object[] values) throws SQLException {
        for (int i = 0; i < values.length; i++) {
            pstmt.setObject(i, values[i]);
        }
        return pstmt.executeQuery();
    }

    private PreparedStatement createPreparedStatement(Connection conn, String sql) throws SQLException {
        return conn.prepareStatement(sql);
    }

    private Connection getConnection() throws SQLException {
        return this.dataSource.getConnection();
    }


}
